﻿using EnvDTE80;
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace JoinBoxAlignPlug
{
    public class SnippetHelper
    {
        /// <summary>
        /// 获取代码片段路径的所有片段文件
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, FileInfo> GetCsSnippet(DTE2 vsDTE2)
        {
            //var dte  = (EnvDTE.DTE)ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE).GUID);
            //var dte  = (DTE)Package.GetGlobalService(typeof(EnvDTE.DTE));

            //"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC#\\Snippets\\2052\\Visual C#"

            var exe = vsDTE2.FullName;                                //@"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe"
            var LCID = vsDTE2.LocaleID;                               //2052 全球语言区域号
            var enterprise = vsDTE2.Edition;                          //"Enterprise"
            var str = exe.Substring(0, exe.LastIndexOf(enterprise));  //@"C:\Program Files (x86)\Microsoft Visual Studio\2019\"
            str += $"{enterprise}\\VC#\\Snippets\\{LCID}";
            //\\Visual C#
            var dir = new DirectoryInfo(str);

            var fis = new Dictionary<string, FileInfo>();
            foreach (var item in dir.GetDirectories())
            {
                var dirSub = item.GetFiles("*.snippet", SearchOption.TopDirectoryOnly);
                foreach (var file in dirSub)
                {
                    var name = Path.GetFileNameWithoutExtension(file.Name);
                    if (!fis.ContainsKey(name))
                        fis.Add(name, file);
                }
            }
            return fis;
        }

    


#if true3
        /// <summary>
        /// 获取代码片段的插入字符串
        /// </summary>
        /// <param name="snippet">代码片段的xml全部字符串</param>
        public static string GetSnippetFileInsertString(string fullName)
        {
            return FileAction(fullName, snippet => {
                return GetInsertString(snippet);
            });
        }

        static string GetInsertString(string snippet)
        {
            var begin = snippet.IndexOf("<Code ");
            if (begin == -1)
                return null;
            var end = snippet.IndexOf("</Code");
            if (end == -1)
                return null;
            snippet = snippet.Substring(begin, end - begin);

            //找到插入的代码
            var cdata = "<![CDATA[";
            var cdataOf = snippet.IndexOf(cdata);
            if (cdataOf == -1)
                return null;
            cdataOf += cdata.Length;
            snippet = snippet.Substring(cdataOf, snippet.Length - cdataOf);
            cdataOf = snippet.IndexOf("]]>");
            if (cdataOf == -1)
                return null;
            snippet = snippet.Substring(0, cdataOf);
            return snippet;
        }


        /// <summary>
        /// 打开路径转为文本,并执行委托
        /// </summary>
        /// <param name="fullName"></param>
        /// <param name="action"></param>
        static string FileAction(string fullName, Func<string, string> action)
        {
            string code = null;
            FileStream fileStream = null;
            BinaryReader binaryReader = null;
            try
            {
                fileStream = new FileStream(fullName, FileMode.Open, FileAccess.Read, FileShare.None);
                binaryReader = new BinaryReader(fileStream, Encoding.UTF8, true);

                //获取文件长度
                byte[] bytes = new byte[fileStream.Length];
                //读取文件中的内容并保存到字节数组中
                binaryReader.Read(bytes, 0, bytes.Length);
                //将字节数组转换为字符串
                string snippet = Encoding.UTF8.GetString(bytes);
                code = action.Invoke(snippet);
            }
            catch (Exception)
            {

            }
            finally
            {
                fileStream?.Close();
                fileStream?.Dispose();

                binaryReader?.Close();
                binaryReader?.Dispose();
            }
            return code;
        }
#endif
    }

}



#if true3
namespace JoinBoxAlignPlug
{
    public class SnippetHelper
    {
        public class SnippetTypes
        {
            /// <summary>
            /// 片段类型
            /// </summary>
            public List<string> SnippetType { get; set; }
        }

        public class Header
        {
            /// <summary>
            /// 标题
            /// </summary>
            public string Title { get; set; }
            /// <summary>
            /// 捷径
            /// </summary>
            public string Shortcut { get; set; }
            /// <summary>
            /// 描述
            /// </summary>
            public string Description { get; set; }
            /// <summary>
            /// 作者
            /// </summary>
            public string Author { get; set; }
            /// <summary>
            /// 片段类型
            /// </summary>
            public SnippetTypes SnippetTypes { get; set; }
        }

        public class LiteralItem
        {
            public string ID { get; set; }
            /// <summary>
            /// 工具提示
            /// </summary>
            public string ToolTip { get; set; }
            /// <summary>
            /// 默认
            /// </summary>
            public string @Default { get; set; }
        }

        public class Declarations
        {
            /// <summary>
            /// 文字
            /// </summary>
            public List<LiteralItem> Literal { get; set; }
        }

        public class Code
        {
            /// <summary>
            /// 语言c#?vb?
            /// </summary>
            public string Language { get; set; }
            /// <summary>
            /// 代码内容
            /// </summary>
            public string CodeString { get; set; }
        }

        public class Snippet
        {
            /// <summary>
            /// 宣言
            /// </summary>
            public Declarations Declarations { get; set; }
            /// <summary>
            /// 代码
            /// </summary>
            public Code Code { get; set; }
        }

        public class CodeSnippet
        {
            /// <summary>
            /// 格式版本号
            /// </summary>
            public string Format { get; set; }
            /// <summary>
            /// 标题
            /// </summary>
            public Header Header { get; set; }
            /// <summary>
            /// 片段
            /// </summary>
            public Snippet Snippet { get; set; }
        }

        public class CodeSnippets
        {
            /// <summary>
            /// xml使用说明
            /// </summary>
            public string xmlns { get; set; }
            /// <summary>
            /// 代码片段
            /// </summary>
            public CodeSnippet CodeSnippet { get; set; }
        }

        public class Root
        {
            public CodeSnippets CodeSnippets { get; set; }
        }
    }
}
#endif
